package com.phenix.apt;

import com.phenix.annotation.apt.Instance;
import com.phenix.annotation.aspect.MemoryCache;
import com.squareup.javapoet.ClassName;
import com.squareup.javapoet.CodeBlock;
import com.squareup.javapoet.JavaFile;
import com.squareup.javapoet.MethodSpec;
import com.squareup.javapoet.TypeSpec;

import java.io.IOException;
import java.util.ArrayList;
import java.util.List;

import javax.annotation.processing.RoundEnvironment;
import javax.lang.model.element.Modifier;
import javax.lang.model.element.TypeElement;
import javax.lang.model.util.ElementFilter;
import javax.tools.Diagnostic;


/**
 * 实例化工厂注解器
 */
class InstanceProcessor implements IProcessor {
    @Override
    public void process(AnnotationProcessor processor, RoundEnvironment roundEnv) {
        String instanceFactory = "InstanceFactory";//设置你要生成代码的class名称
        TypeSpec.Builder tb = TypeSpec.classBuilder(instanceFactory)
                .addModifiers(Modifier.PUBLIC, Modifier.FINAL)
                .addJavadoc("@ 实例化工厂 此类由apt自动生成");
        MethodSpec.Builder mb1 = MethodSpec.methodBuilder("create")
                .addAnnotation(MemoryCache.class)
                .addJavadoc("@此方法由apt自动生成")
                .addModifiers(Modifier.PUBLIC, Modifier.STATIC)
                .addParameter(Class.class, "mClass")
                .addException(IllegalAccessException.class)
                .addException(InstantiationException.class)
                .returns(Object.class);

        MethodSpec.Builder mb2 = MethodSpec.methodBuilder("create")
                .addJavadoc("@此方法由apt自动生成")
                .addModifiers(Modifier.PUBLIC, Modifier.STATIC)
                .addParameter(Class.class, "mClass")
                .addParameter(ClassName.get("android.view", "View"), "view")
                .returns(Object.class);

        List<ClassName> list = new ArrayList<>();
        CodeBlock.Builder block1 = CodeBlock.builder().beginControlFlow(" switch (mClass.getSimpleName())");//括号开始
        CodeBlock.Builder block2 = CodeBlock.builder().beginControlFlow(" switch (mClass.getSimpleName())");
        TypeElement tElement = null;
        for (TypeElement element : ElementFilter.typesIn(roundEnv.getElementsAnnotatedWith(Instance.class))) {
            processor.mMessager.printMessage(Diagnostic.Kind.NOTE, "正在处理：" + element.toString());
            if (null == tElement) tElement = element;
            if (!Utils.isValidClass(processor.mMessager, element)) return;
            ClassName currentType = ClassName.get(element);
            if (list.contains(currentType)) continue;
            list.add(currentType);
            if (element.getAnnotation(Instance.class).type() == Instance.NORMAL)
                block1.addStatement("case $S:return new $T()", currentType.simpleName(), currentType);
            else if (element.getAnnotation(Instance.class).type() == Instance.VIEW_HOLDER) {
                block2.addStatement("case $S:return new $T(view)", currentType.simpleName(), currentType);
            }

        }
        block1.addStatement("default: return mClass.newInstance()");
        block1.endControlFlow();
        mb1.addCode(block1.build());
        block2.addStatement("default: return null");
        block2.endControlFlow();
        mb2.addCode(block2.build());

        tb.addMethod(mb1.build());
        tb.addMethod(mb2.build());

        if (null != tElement) {
            try {
                JavaFile javaFile = JavaFile.builder(Utils.GE_WHERE, tb.build()).build();// 生成源代码
                javaFile.writeTo(processor.mFiler);// 在 app module/build/generated/source/apt 生成一份源代码
//            javaFile.writeTo(new File(System.getProperty("user.home") + "/Desktop/")); // 测试在桌面生成一份源代码,方便查看
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }
}
